package com.zxd.interview.util.encrypt;

import com.zxd.interview.util.PreconditionUtils;
import com.zxd.interview.util.StringUtils;
import org.apache.commons.codec.binary.Base64;

import javax.crypto.*;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

/**
 * AES 加解密工具类
 *
 * @author Administrator
 */
public class AESUtils {
    //密钥
    private static String KEY = "x3/eqbraBj0pFyKLza21lq3nj7TP31Wz86DQZEKEszm9NRO/JxKmUTpwBOBslGF0xS3NtT2m3EHYieymCMbQQ/8j68SZNg/5DHH+pznp3P5f65lcIYsVh3mP5fjhPI6vaYthmG0QOd/bFjzxrSMvP8Fi=/vHezHNwiZ8siAcQF3yXgStuTE3tH9tV8IOLJPpRrjRXqNCAOCjVZtpJRun6OBb";

    /**
     * 签名算法
     */
    private static final String SIGN_ALGORITHMS = "SHA1PRNG";

    /**
     * 对于内容进行指定秘钥加密
     *
     * @param content 原始数据内容
     * @return
     */
    public static String encodeAes(String content) {
        return encodeAes(content, KEY);
    }

    /**
     * aes 加密
     * 需要指定秘钥，否则会抛出异常信息
     *
     * @param content 原始内容
     * @param pkey    加密key
     * @return
     */
    public static String encodeAes(String content, String pkey) {
        PreconditionUtils.checkArgument(StringUtils.isNotBlank(pkey), "秘钥不能为空");
        try {
            // 1.构造密钥生成器，指定为AES算法,不区分大小写
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            //故调整为如下方式
            SecureRandom random = SecureRandom.getInstance(SIGN_ALGORITHMS);
            random.setSeed(pkey.getBytes(StandardCharsets.UTF_8));
            keygen.init(128, random);
            SecretKey original_key = keygen.generateKey();
            byte[] raw = original_key.getEncoded();
            SecretKey key = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.ENCRYPT_MODE, key);
            byte[] byte_encode = content.getBytes(StandardCharsets.UTF_8);
            byte[] byte_AES = cipher.doFinal(byte_encode);
            return new String(Base64.encodeBase64(byte_AES));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 对于指定内容进行解密，需要传递解密的秘钥
     *
     * @param content 加密原始内容
     * @param pkey    内置秘钥
     * @return
     */
    public static String decodeAes(String content) {
        return decodeAes(content, KEY);
    }

    /**
     * 对于指定内容进行解密，需要传递解密的秘钥
     *
     * @param content 加密原始内容
     * @param pkey    加密key
     * @return
     */
    public static String decodeAes(String content, String pkey) {
        PreconditionUtils.checkArgument(StringUtils.isNotBlank(pkey), "秘钥不能为空");
        try {
            KeyGenerator keygen = KeyGenerator.getInstance("AES");
            //故调整为如下方式
            SecureRandom random = SecureRandom.getInstance(SIGN_ALGORITHMS);
            random.setSeed(pkey.getBytes(StandardCharsets.UTF_8));
            keygen.init(128, random);
            SecretKey original_key = keygen.generateKey();
            byte[] raw = original_key.getEncoded();
            SecretKey key = new SecretKeySpec(raw, "AES");
            Cipher cipher = Cipher.getInstance("AES");
            cipher.init(Cipher.DECRYPT_MODE, key);
            byte[] byte_content = Base64.decodeBase64(content);
            byte[] byte_decode = cipher.doFinal(byte_content);
            return new String(byte_decode, StandardCharsets.UTF_8);
        } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) {
            throw new RuntimeException(e);
        }
    }

}
